﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using KBEngine.Export;
using KBEngine.Setting;
using KBEngine.Setting.TypeDef;

namespace KBEngineTool
{
    public class EntityDef
    {
        public string Name;
        public ClassType EntityType;

        public bool HasClient;
        public bool IsRegistered;
        public EntityDef Parent;
        public VolatileDef Volatile = new VolatileDef();
        public List<EntityDef> Interfaces = new List<EntityDef>();
        public List<ComponentDef> Components = new List<ComponentDef>();
        public List<PropertyDef> Properties = new List<PropertyDef>();

        public List<MethodDef> ClientMethods = new List<MethodDef>();
        public List<MethodDef> BaseMethods = new List<MethodDef>();
        public List<MethodDef> CellMethods = new List<MethodDef>();
        public EntityDef(string name, bool isInterface)
        {
            Name = name;
            EntityType = isInterface ? ClassType.Interfaces : ClassType.None;
        }


        public static Dictionary<string, EntityDef> AllEntityDefs = new Dictionary<string, EntityDef>();
        public static List<BaseType> AllTypes = new List<BaseType>();

        static EntityLoader entityDefMgr = new EntityLoader();
        public static void LoadFromFile(string entityDefFolder, string entitiesXML, string typesXML)
        {
            entityDefMgr.Read(entityDefFolder, entitiesXML, typesXML);
            AllEntityDefs.Clear();
            AllTypes = entityDefMgr.AllTypes;
            foreach (var item in entityDefMgr.AllEntitySetting)
            {
                AllEntityDefs.Add(item.Key, new EntityDef(item.Key, false));
            }
            foreach (var item in AllEntityDefs)
            {
                item.Value.FromSetting(entityDefMgr, entityDefMgr.AllEntitySetting[item.Key]);
            }
        }
        public static bool WriteToFile(string userTypeFolder)
        {
            entityDefMgr.AllEntitySetting.Clear();
            foreach (var item in AllEntityDefs)
            {
                var setting = item.Value.ToSetting(entityDefMgr);
                entityDefMgr.AllEntitySetting.Add(setting.name, setting);
            }
            return entityDefMgr.Write(userTypeFolder);
        }
        public static string[] AllTypeNamesExlude(BaseType type)
        {
            return (from t in AllTypes
                    where t != type
                    select t.TypeName).ToArray();
        }
    }
    public class ComponentDef
    {
        public string Name;
        public EntityDef Component;
        public bool? Persistent;
    }
    public class VolatileDef
    {
        public float? Position;
        public float? Yaw;
        public float? Pitch;
        public float? Roll;
        public bool optimized;
    }
    public class PropertyDef
    {
        public string Name;
        public IType Type = EntityDef.AllTypes[0];
        public string Default;
        public UInt16? Utype;
        public Flags Flags = Flags.CELL_PRIVATE;
        public bool? Persistent;
        public uint? DatabaseLength;
        public IndexType? IndexType;

        public override string ToString()
        {
            return string.Format("Name:{0},Type:{1},Utype:{2},Flags:{3},Persistent:{4},DatabaseLength:{5},IndexType:{6}", Name, Type, Utype, Flags, Persistent, DatabaseLength, IndexType);
        }
    }
    public class MethodDef
    {
        public string Name;
        public bool Exposed;
        public ushort? Utype;
        public List<IType> Args = new List<IType>();

        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();

            sb.AppendFormat("Name:{0} Exposed:{1} Utype:{2} ", Name, Exposed, Utype);
            if (Args.Count > 0)
            {
                sb.Append('[');
                foreach (var item in Args)
                    sb.AppendFormat("type:{0} ", item.TypeName);
                sb.Append(']');
            }
            return sb.ToString();
        }
    }
}
